package com.hoo.controller.account;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.util.WebUtils;
import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.util.*;
import com.hoo.common.constant.Constant;
import com.hoo.auth.MyRealm.UserContext;

public abstract class BaseController {
    /**
     * 日志对象
     */
    protected Logger logger = LoggerFactory.getLogger(getClass());
/*
    @Autowired
    protected Validator validator;

    *//**
     * 服务端参数有效性验证
     *
     * @param object 验证的实体对象
     * @param groups 验证组
     * @return 验证成功：返回true；严重失败：将错误信息添加到 message 中
     *//*
    protected boolean beanValidator(Model model, Object object, Class<?>... groups) {
        try {
            BeanValidators.validateWithException(validator, object, groups);
        } catch (ConstraintViolationException ex) {
            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
            list.add(0, "数据验证失败：");
            addMessage(model, list.toArray(new String[]{}));
            return false;
        }
        return true;
    }

    *//**
     * 服务端参数有效性验证
     *
     * @param object 验证的实体对象
     * @param groups 验证组
     * @return 验证成功：返回true；严重失败：将错误信息添加到 flash message 中
     *//*
    protected boolean beanValidator(RedirectAttributes redirectAttributes, Object object,
                                    Class<?>... groups) {
        try {
            BeanValidators.validateWithException(validator, object, groups);
        } catch (ConstraintViolationException ex) {
            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
            list.add(0, "数据验证失败：");
            addMessage(redirectAttributes, list.toArray(new String[]{}));
            return false;
        }
        return true;
    }
*/
    /**
     * 添加Model消息
     *
     * @param messages 消息
     */
    protected void addMessage(Model model, String... messages) {
        StringBuilder sb = new StringBuilder();
        for (String message : messages) {
            sb.append(message).append(messages.length > 1 ? "<br/>" : "");
        }
        model.addAttribute("message", sb.toString());
    }

    /**
     * 添加Flash消息
     *
     * @param messages 消息
     */
    protected void addMessage(RedirectAttributes redirectAttributes, String... messages) {
        StringBuilder sb = new StringBuilder();
        for (String message : messages) {
            sb.append(message).append(messages.length > 1 ? "<br/>" : "");
        }
        redirectAttributes.addFlashAttribute("message", sb.toString());
    }

    /**
     * 初始化数据绑定 1. 将所有传递进来的String进行HTML编码，防止XSS攻击 2. 将字段中Date类型转换为String类型
     */
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        // String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
        binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
            }

            @Override
            public String getAsText() {
                Object value = getValue();
                return value != null ? value.toString() : "";
            }
        });
        // Date 类型转换
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                try {
                    setValue(DateUtils.parseDate(text));
                } catch (ParseException e) {
                    logger.error(e.getMessage());
                }
            }
        });
    }

    protected Map<String, Object> dataTableJson(int totalCount, List<?> dataList) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("iTotalDisplayRecords", totalCount);
        data.put("iTotalRecords", totalCount);
        data.put("aaData", dataList == null ? Collections.EMPTY_LIST : dataList);
        Map<String, Object> map = new HashMap<String, Object>();
        if (CollectionUtils.isEmpty(dataList)) {
            map.put("result", Constant.ERROR);
        } else {
            map.put("result", Constant.SUCCESS);
        }
        map.put("data", data);
        return map;
    }

    protected Map<String, Object> data2json(List<?> data) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (CollectionUtils.isEmpty(data)) {
            map.put("result", Constant.ERROR);
        } else {
            map.put("result", Constant.SUCCESS);
        }
        map.put("data", data);
        return map;
    }

    protected Map<String, Object> data2json(Object data) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (data == null) {
            map.put("result", Constant.ERROR);
        } else {
            map.put("result", Constant.SUCCESS);
        }
        map.put("data", data);
        return map;
    }

    protected UserContext getUserContext() {
        UserContext userContext = (UserContext) SecurityUtils.getSubject().getPrincipal();
        return userContext;
    }

    protected Integer getCurrentUserId() {
        return getUserContext().getId();
    }

    protected String getCurrentUsercode() {
        return getUserContext().getUsercode();
    }

    protected Integer getCurrentUserParentUserId() {
        return getUserContext().getParentUserId();
    }

    protected String getCurrentUserParentUsercode() {
        return getUserContext().getParentUsercode();
    }

    // 插入操作记录监控的方法
    public void saveOptLog(HttpServletRequest request, String eventId, String eventName,
                           String objectId) {

        String no = (String) WebUtils.getSessionAttribute(request, "no");
        String name = (String) WebUtils.getSessionAttribute(request, "name");

        // 插入操作记录
        /*
         * OperatorLog optLog = new OperatorLog(); optLog.setEventId(eventId);
         * optLog.setEventName(eventName); optLog.setEventTime(new Date());
         * optLog.setObjectId(objectId); optLog.setOptNo(no); optLog.setOptName(name);
         * optLog.setIp();
         * 
         * try { this.operatorLogService.save(optLog); } catch (DataAccessException dae) {
         * logger.error("save operatorLog failed", dae); }
         */
    }

    protected Map<String, Object> ajaxSuccess() {
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("result", "ok");
        jsonMap.put("rescode", 200);
        jsonMap.put("msg", "操作成功");
        return jsonMap;
    }

    protected Map<String, Object> ajaxSuccess(Object data) {
        Map<String, Object> retMap = new HashMap<String, Object>();
        retMap.put("data", data);
        retMap.put("result", "ok");
        retMap.put("rescode", 200);
        return retMap;
    }

    protected Map<String, Object> ajaxFail() {
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("result", "fail");
        jsonMap.put("msg", "系统繁忙，请稍后再试");
        return jsonMap;
    }

    protected Map<String, Object> ajaxFail(String msg) {
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("result", "fail");
        jsonMap.put("msg", msg);
        return jsonMap;
    }

    protected Map<String, Object> ajaxFail(int resCode, String msg) {
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("result", "fail");
        jsonMap.put("rescode", resCode);
        jsonMap.put("msg", msg);
        return jsonMap;
    }

    protected Map<String, Object> ajaxFail(String key, String msg, int resCode) {
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("result", "fail");
        jsonMap.put("rescode", resCode);
        jsonMap.put(key, msg);
        return jsonMap;
    }

    protected Map<String, Object> badParamMap(String key, String msg) {
        Map<String, Object> retMap = new HashMap<String, Object>();
        retMap.put("result", "badparam");
        retMap.put("msg", "参数错误");
        Map<String, Object> data = new HashMap<String, Object>();
        data.put(key, msg);
        retMap.put("data", data);
        return retMap;
    }
    /**
     * ************************************************************************
     * 获取提交参数，取不到就以空字符串代之
     *
     * @param key
     * @return
     */
    protected String getParameter(HttpServletRequest request, String key) {
        return request.getParameter(key) == null ? "" : request.getParameter(key).trim();
    }

    /**
     * ************************************************************************
     * 获取提交参数，取不到就报参数以定义字符串代替
     *
     * @param key
     * @return
     */
    protected String getParameterForDefValue(HttpServletRequest request, String key, String defValue) {
        return request.getParameter(key) == null ? defValue : request.getParameter(key).trim();
    }

    /**
     * ************************************************************************
     * 获取提交参数，取不到就报参数无法获取之异常
     *
     * @param key
     * @return
     */
    protected String getParameter(HttpServletRequest request, String key, boolean isNeed) {
        String result = getParameter(request, key);
        if (isNeed && result.equals("")) {
            throw new RuntimeException(key + " badParme");
        }
        return result;
    }

}
